package tifclient

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"

	"gitee.com/saroeleven/ginrcpv2/etcdmgr/dispatch"
)

const timeOut = 5 * time.Second

/*
http client
*/
type client struct {
	url    string
	header http.Header
	cli    *http.Client
}

type clientOption func(*client)

func NewClient(svcName, svcUrl string, opts ...clientOption) *client {
	c := &client{cli: &http.Client{}}
	//初始化svc url
	var svcAddr = dispatch.NewAddress(svcName, dispatch.WithWeight()).Addr()
	c.url = fmt.Sprintf("http://%s/%s", svcAddr, svcUrl)

	for _, opt := range opts {
		opt(c)
	}
	return c
}

func WithHeaderFiled(key string, value string) clientOption {
	return func(c *client) {
		c.header.Add(key, value)
	}
}

func WithHeader(header http.Header) clientOption {
	return func(c *client) {
		c.header = header
	}
}

// post json
func (c *client) Post(ctx context.Context, data any) ([]byte, error) {
	w := bytes.NewBuffer([]byte{})
	if err := json.NewEncoder(w).Encode(data); err != nil {
		return nil, err
	}
	httpCtx, cancel := context.WithTimeout(ctx, timeOut)
	defer cancel()
	request, err := http.NewRequestWithContext(httpCtx, "POST", c.url, w)
	if err != nil {
		return nil, err
	}

	for key, value := range c.header {
		request.Header[key] = value
	}

	response, err := c.cli.Do(request)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = response.Body.Close()
	}()
	responseBody, err := io.ReadAll(response.Body)
	return responseBody, err
}
